Git 提交相关
Git 的结构
- 本地库:历史版本
- 暂存区:打算提交,但是还没提交的地方
- 工作区
提交相关
Git Commit
Git 把数据看作是小型文件系统的一组快照。每次提交更新时 Git 都会对当前的全部文件制作一个快照,并保存这个 快照 的索引。
为了高效,如果文件没有修改,Git 不再重新储存该文件,而是只保留一个链接指向之前存储的文件。所以 Git 的工作方式可以称之为快照流
Git 还保存了提交的历史记录。这也是为什么大多数提交记录的上面都有父节点的原因
# 提交命令
git commit filename
提交命令具体使用
git add # 把工作区代码提交到缓存区
git rm --cached filename # 把文件从缓存区删除(不是删掉工作区的文件)
git commit filename # 提交缓存区的文件本地库(提交后自动进入vim请你输入提交的修改信息,类似注释)
注意:对于仓库中没有的文件,git commit file
不能提交,所以当库里不存在那个文件时,必须先 add
,当库里已经有那个文件之后 修改文件可以不 add
直接 commit
git commit -m "这里是注释" filename
注意:如果不加 -m
参数,会进入 vim 编辑器
如果是直接提交(省略add这步)则用 git commit -a
,但是就无法撤销了。
git restore filename
撤销修改(注意旧版用的是git checkout
)
如果要提交全部文件,则直接用 .
代替就行了
git add .
git commit -m"注释" .
追加提交
如果我们不小心提交了一版我们不满意的代码,并且给它推送到服务器了,在代码没被 merge
之前我们希望再修改一版满意的,而如果我们不想在服务器上 abondon,那么我们怎么做呢?
git commit --amend
这个 amend
参数也叫追加提交,它可以在不增加一个新的 commit-id 的情况下将新修改的代码追加到前一次的 commit-id 中
假如现在版本库里最近的一版正是我们想要追加进去的那版(就是处于当前最新的版本),此时是最简单的,直接修改工作区代码,然后 git add
,之后就可以直接进行 git push
到服务器,中间不需要进行其他的操作如 git pull
等
如果现在版本库里最近的一版不是我们想要追加进去的那版,那么此时我们需要将版本库里的版本回退到我们想要追加的那一版,想要将版本回退到我们想要的哪一版可以使用 gitk
或其他的图形界面化工具。
在终端输入 gitk
,回车,会弹出 gitk
的图形界面,在界面的左侧部分陈列着版本库中的一条条 commit-id,此时选中我们需要的那一版,右键点击之后会弹出一个 选择菜单,如果是在 master 分支上,那么其中会有一项是 Reset master branch to here,点击这项,会弹出一个名为 confirm reset 的确认 box,选择 reset type 中的 hard 项,再点击 OK
关闭gitk图形界面,回到终端,运行 git log -1
命令,发现现在版本库里最近的一次提交已经是我们希望的那一版了,此时再在工作区直接修改代码,改完之后进行 git add
,再执行本 git commit --amend
命令,之后 git push
再使用命令打印一下它们的图状关系
git log --graph --decorate --oneline --simplify-by-decoration --all
当然,上面的操作可以使用命令来实现,如下所示:
如果我们不知道我们需要的版本与现在最近的版本中间隔着 n 个提交,那么我们可以使用 git log
来查看版本库中的 commit-id,找到我们需要的 commit-id 后,在终端中执行
git reset --hard commit-id
这个命令执行完后,运行 git log -1
命令我们会发现现在版本库里最近的一版就是我们需要的那版,此时再在工作区直接修改代码,改完之后进行 git add
再执行本 git commit --amend
命令,之后 git push
Git Tags 添加锚点
Tags 它们可以永久地将某个特定的提交命名为里程碑,然后就可以像分支一样引用了。(在某种程度上的永久 —— 因为标签可以被删除后可以重新在另外一个位置创建同名的标签)
更难得的是,它们并不会随着新的提交而移动。你也不能到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。
咱们来看看标签到底是什么样。
Git示范:
咱们先建立一个标签,指向提交记录 C1,表示这是我们 1.0 版本。
git tag v1 c1
我们将这个标签命名为 v1,并且明确地让它指向提交记录 C1,如果你不指定提交记录,Git 会用 HEAD 所指向的位置。
Git Describe 找到最近的锚点
由于标签在代码库中起着 “锚点” 的作用,Git 还为此专门设计了一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe
!
Git Describe 能帮你在提交历史中移动了多次以后找到方向;当你用 git bisect
(一个查找产生 Bug 的提交记录的指令)找到某个提交记录时,或者是当你坐在你那刚刚度假回来的同事的电脑前时, 可能会用到这个命令。
git describe
的语法是:
git describe <ref>
<ref>
可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所 checkout
的位置(HEAD)。
它输出的结果是这样的:
<tag>_<numCommits>_g<hash>
tag 表示的是离 ref 最近的标签, numCommits 是表示这个 ref 与 tag 相差有多少个提交记录,hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
当 ref 提交记录上有某个标签时,则只输出标签名称
如下例子所示:
git tag v2 c3
然后执行下面的命令
git describe master
# 会输出:v1_2_gC2
git describe side
# 会输出:v2_1_gC4
隐藏 Stash 操作
假设您正在为产品新的功能编写/实现代码,当正在编写代码时,突然出现软件客户端升级。这时,您必须将新编写的功能代码保留几个小时然后去处理升级的问题。在这段时间内不能提交代码,也不能丢弃您的代码更改。 所以需要一些临时等待一段时间,您可以存储部分更改,然后再提交它。
在 Git 中,隐藏操作将使您能够修改跟踪文件,阶段更改,并将其保存在一系列未完成的更改中,并可以随时重新应用。
现在,要切换分支以进行客户升级,但不想提交一直在做的工作; 那么可以把当前工作的改变隐藏起来。 要将一个新的存根推到堆栈上,运行 git stash
命令。
$ git stash
现在,工作目录是干净的,所有更改都保存在堆栈中。 现在使用 git status
命令来查看当前工作区状态。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
现在,可以安全地切换分支并在其他地方工作。通过使用 git stash list
命令来查看已存在更改的列表。
$ git stash list
stash@{0}: WIP on master: ef07ab5 synchronized with the remote repository
假设您已经解决了客户升级问题,想要重新开始新的功能的代码编写,查找上次没有写完成的代码,只需执行 git stash pop
命令即可从堆栈中删除更改并将其放置在当前工作目录中。